//
//  PanSwiper.m
//  PanPush
//
//  Created by lpc on 16/3/16.
//  Copyright © 2016年 lpc. All rights reserved.
//

#import "PanSwiper.h"
#import "PanAnimator.h"
#import "PanPopAnimator.h"
#import "PanPushAnimator.h"

@interface PanSwiper () <UINavigationControllerDelegate>

@property (weak, readwrite, nonatomic) UIPanGestureRecognizer *panRecognizer;
@property (weak, nonatomic) IBOutlet UINavigationController *navigationController;
@property (strong, nonatomic) UIPercentDrivenInteractiveTransition *interactionController;

@property (strong, nonatomic) PanAnimator *animator;
@property (assign, nonatomic) BOOL isDuringAnimation;   //Default is NO;

@end

@implementation PanSwiper
#pragma mark - Lifecycle

- (void)dealloc
{
    [_panRecognizer removeTarget:self action:@selector(handleWithPanGestureRecongizer:)];
    [_navigationController.view removeGestureRecognizer:_panRecognizer];
}

- (instancetype)initWithNavigationController:(UINavigationController *)navigationController
{
    NSCParameterAssert(!!navigationController);

    self = [super init];
    if (self) {
        _navigationController = navigationController;
        _navigationController.delegate = self;
        [self commonInit];
    }
    return self;
}

- (void)awakeFromNib
{
    [self commonInit];
}

- (void)commonInit
{
    UIGestureRecognizer *gesture = self.navigationController.interactivePopGestureRecognizer;
    gesture.enabled = NO;
    UIView *gestureView = gesture.view;

    UIPanGestureRecognizer *popRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleWithPanGestureRecongizer:)];;
    popRecognizer.maximumNumberOfTouches = 1;
    [gestureView addGestureRecognizer:popRecognizer];
    self.panRecognizer = popRecognizer;
}


#pragma mark -- 偏移量、速度 --
//偏移量
- (CGFloat)translationWithPanGestureRecongizer:(UIPanGestureRecognizer *)panGestureRecognizer
{
    CGPoint point = [panGestureRecognizer translationInView:panGestureRecognizer.view];
    return point.x;
}

//速度
- (CGFloat)velocityWithPanGestureRecongizer:(UIPanGestureRecognizer *)panGestureRecognizer
{
    CGPoint point = [panGestureRecognizer velocityInView:panGestureRecognizer.view];
    return point.x;
}


#pragma mark -- PanGesture Response --

- (void)handleWithPanGestureRecongizer:(UIPanGestureRecognizer *)recognizer
{
    CGFloat off_X = [self translationWithPanGestureRecongizer:recognizer];
    off_X = ABS(off_X);
    CGFloat progress = off_X / recognizer.view.bounds.size.width;
    progress = MIN(1.0, MAX(0.0, progress));

    if (recognizer.state == UIGestureRecognizerStateBegan) {
        self.isDuringAnimation = YES;
        self.interactionController = nil;

        CGFloat velocity_X = [self velocityWithPanGestureRecongizer:recognizer];

        if (velocity_X > 0) {
            //Pop
            self.animator = [PanPopAnimator new];
            self.interactionController = [[UIPercentDrivenInteractiveTransition alloc] init];
            [self.navigationController popViewControllerAnimated:YES];
        }
        else if (velocity_X < 0){
            //Push
            if (_delegate && [_delegate respondsToSelector:@selector(beginPanPushToNextControllerForPanSwiper:)]) {
                UIViewController *nextController = [self.delegate beginPanPushToNextControllerForPanSwiper:self];
                if (nextController && [nextController isKindOfClass:[UIViewController class]])
                {
                    self.animator = [PanPushAnimator new];
                    self.interactionController = [[UIPercentDrivenInteractiveTransition alloc] init];
                    [self.navigationController pushViewController:nextController animated:YES];
                }
            }
        }
    }
    else if (recognizer.state == UIGestureRecognizerStateChanged) {
        [self.interactionController updateInteractiveTransition:progress];
    }
    else if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled) {

        if (progress > 0.5) {
            [self.interactionController finishInteractiveTransition];
        }
        else {
            [self.interactionController cancelInteractiveTransition];
        }
        self.interactionController = nil;
        self.isDuringAnimation = NO;

        if (_delegate && [_delegate respondsToSelector:@selector(didEndPanPushToNextControllerForPanSwiper:)]) {
            [self.delegate didEndPanPushToNextControllerForPanSwiper:self];
        }
    }
}



#pragma mark - UINavigationControllerDelegate

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    if (self.isDuringAnimation) {
        if (operation == UINavigationControllerOperationPop || operation == UINavigationControllerOperationPush) {
            return self.animator;
        }
        return nil;
    }
    return nil;
}

- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
{
    return self.interactionController;
}

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    self.isDuringAnimation = NO;

//    if (navigationController.viewControllers.count >= 2 && (!self.isForbidDragBack)) {
//        self.panRecognizer.enabled = YES;
//    }
//    else {
//        self.panRecognizer.enabled = NO;
//    }
}

@end
